package com.zh.jwt.common.exception;

import com.zh.jwt.common.enums.BizEnum;
import com.zh.jwt.common.model.ApiResult;
import com.zh.jwt.common.model.PathNotFoundModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局通用异常处理器
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    /**
     * Token异常处理
     */
    @ExceptionHandler(UnauthorizedException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ApiResult<String> unauthorizedErrorHandler(UnauthorizedException e) {
        log.error(e.getMessage());
        return ApiResult.fail(e.getBizEnum());
    }

    /**
     * 默认异常处理
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ApiResult<String> defaultErrorHandler(Exception e) {
        log.error(e.getMessage());
        return ApiResult.fail(BizEnum.SYSTEM_ERROR);
    }

    /**
     * 404处理
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ApiResult<PathNotFoundModel> notFountHandler(HttpServletRequest request, NoHandlerFoundException e) {
        String method = request.getMethod();
        String path = request.getRequestURI();
        return ApiResult.fail(new PathNotFoundModel(
                method,
                path
        ), "404，请求路径不存在");
    }

    /**
     * 请求参数错误异常处理
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult<String> requestParameterMissingErrorHandler(MissingServletRequestParameterException e) {
        log.error(e.getMessage());
        return ApiResult.fail("请求参数不符合接口要求，" + e.getMessage());
    }

    /**
     * 请求方式不支持的异常处理
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public ApiResult<String> requestMethodNotSupportedErrorHandler(HttpRequestMethodNotSupportedException e) {
        log.error(e.getMessage());
        return ApiResult.fail("请求方法不支持，" + e.getMessage());
    }

    /**
     * 业务异常处理
     */
    @ExceptionHandler(BizException.class)
    @ResponseStatus(HttpStatus.OK)
    public ApiResult<String> jsonErrorHandle(BizException e) {
        log.error(e.getMessage());
        return ApiResult.fail(e.getCode(), e.getMessage());
    }
}